import { Component, OnInit, OnChanges, EventEmitter, Input, Output, SimpleChanges } from '@angular/core';
import { DateFormatService } from '../utils/format.service';

@Component({
  selector: 'el-date-table',
  templateUrl: './date-table.component.html'
})
export class DateTableComponent implements OnInit, OnChanges {
  @Input() model: number = 0;
  @Input() disabledDate: any;
  @Output() modelChange: EventEmitter<any> = new EventEmitter();
  @Input() weeks: Array<string> = ['日', '一', '二', '三', '四', '五', '六'];
  @Input() tableRows: Array<any> = [[], [], [], [], [], []];;
  @Input() targetDay: number = 0;
  @Input() targetMonthOffset: number = 0;
  @Input() date!: Date;
  @Input() today: number = 0;
  @Input() currentMonthOffset: number = 0;

  constructor() { }

  BuildMonthStartRow(first: number, lastCount: number): any {
    var /** @type {?} */ lastday = 7 - first;
    // first loop
    lastCount++;
    lastday++;
    return [0, 1, 2, 3, 4, 5, 6].map(function () {
      lastday--;
      if (lastday > 0)
        return { day: lastday, monthOffset: 0 };
      lastCount--;
      return { day: lastCount, monthOffset: -1 };
    }).reverse();
  };


  isToday(item: any): boolean {
    if (this.currentMonthOffset === null)
      return false;
    return item.monthOffset === this.currentMonthOffset && this.today === item.day;
  };


  isTargetDay(item: any): boolean {
    return item.monthOffset === this.targetMonthOffset && item.day === this.targetDay;
  };


  clickHandle(item: any): void {
    var /** @type {?} */ date = this.date;
    var /** @type {?} */ currentMonth = date.getMonth() + 1;
    var /** @type {?} */ targetMonth = currentMonth + item.monthOffset;
    // update target and update view
    this.targetDay = item.day;
    this.targetMonthOffset = item.monthOffset;
    // get time and emit a number
    date.setMonth(targetMonth - 1);
    date.setDate(item.day);
    this.modelChange.emit(date.getTime());
  };


  getRows(): void {
    var that = this;
    var /** @type {?} */ date = this.date;
    this.targetDay = date.getDate();
    this.today = new Date().getDate();
    this.currentMonthOffset = DateFormatService.getCurrentMonthOffset(date);
    var /** @type {?} */ lastMonth = date.getMonth() - 1;
    var /** @type {?} */ lastYear = lastMonth < 0 ? date.getFullYear() - 1 : date.getFullYear();
    var /** @type {?} */ currentMonthdayCount = DateFormatService.getDayCountOfMonth(date.getFullYear(), date.getMonth());
    var /** @type {?} */ lastMonthDayCount = DateFormatService.getDayCountOfMonth(lastYear, lastMonth < 0 ? 12 : lastMonth);
    var /** @type {?} */ firstDay = DateFormatService.getFirstDayOfMonth(date);
    var /** @type {?} */ nextMonthDay = 0;
    this.tableRows = this.tableRows.map(function (row, index) {
      if (index === 0) {
        return that.BuildMonthStartRow(firstDay, lastMonthDayCount);
      }
      var /** @type {?} */ thisWeekFirstDay = 7 - firstDay + 7 * (index - 1);
      return new Array(7).fill(0).map(function (v, i) {
        var /** @type {?} */ start = thisWeekFirstDay + i + 1;
        if (start <= currentMonthdayCount)
          return { day: start, monthOffset: 0 };
        nextMonthDay++;
        return { day: nextMonthDay, monthOffset: 1 };
      });
    });
  };


  ngOnInit(): void {
    this.date = new Date(this.model);
    this.getRows();
  };


  ngOnChanges(changes: SimpleChanges): void {
    if (!changes || !changes.model)
      return;
    // first change
    if (changes.model.isFirstChange())
      return;
    this.model = changes.model.currentValue;
    this.date = new Date(this.model);
    this.getRows();
  };

}
